/** 使用的方法 */
import crypto from "sm-crypto";
let roles = new Set(); // 拥有的角色(角色名称构成的集合，方便进行检查)
import request from "@/utils/request.ts";
import { usePiniaStore } from "@/pinia/index.ts";
import { homeStore } from "@/pinia/homeStore.ts";
import router from "@/router/index";
import pageFiles from "@/utils/pageFiles.ts";
import common from "@/utils/common.ts";

const utils = {
  /**
   * 截取字符串
   * @param {*} str 字符串
   * @param {*} num 要截取的字符串长度
   */
  cutOutsubString(str: string | any[], num: number, symbol: string) {
    symbol = symbol || "...";
    str = String(str);
    num = Math.floor(Number(num)) || 10;
    if (str.length > num) {
      return str.slice(0, num) + symbol;
    } else {
      return str;
    }
  },
  /**
   * sm4加密
   * @param val 需要加密的数据
   * @returns 返回加密的数据
   */
  encryptPassworld: (val: any) => {
    return crypto.sm4.encrypt(val, "4f9e0a9e523ca213610b361ed8a564f5");
  },
  /** 手机、电话脱敏(手机号保留前3位和后4位,电话保留后4位) */
  desensitizePhone(str: string) {
    str = String(str);
    let val;
    if (str.length == 11) {
      val = str.substr(0, 3) + "****" + str.substr(str.length - 4);
    } else {
      val = "****" + str.substr(str.length - 4);
    }
    return val;
  },
  /** 姓名脱敏(保留最后一个汉字) */
  desensitizeName(str: string) {
    str = String(str);
    if (str.length < 3) {
      return "*" + str.substr(str.length - 1);
    } else {
      return "**" + str.substr(str.length - 1);
    }
  },
  /** 身份证脱敏(保留前3位 后四位) */
  desensitizePaperWork(str: string) {
    str = String(str);
    return str.substr(0, 3) + "***********" + str.substr(str.length - 4);
  },
  /** 邮箱脱敏(保留前4位) */
  desensitizeMailbox(str: string) {
    str = String(str);
    return str.substr(0, 4) + "**********";
  },
  /** 日期脱敏(保留年份) */
  desensitizeBirthDate(str: string) {
    str = String(str);
    return str.substr(0, 4) + "****";
  },
  /** 卡号脱敏(保留头6位bin，最后4位，星号和原卡号位数保持一致,有16位和19位) */
  desensitizeCardNo(str: string) {
    str = String(str);
    if (str.length == 16) {
      return str.substr(0, 6) + "******" + str.substr(str.length - 4);
    } else {
      return str.substr(0, 6) + "*********" + str.substr(str.length - 4);
    }
  },
  /** 钱包编号脱敏(保留头6位bin，最后4位) */
  desensitizeWalletNo(str: string) {
    str = String(str);
    return str.substr(0, 6) + "******" + str.substr(str.length - 4);
  },
  /** 地址脱敏(保留后4个汉字) */
  desensitizeAddress(str: string) {
    str = String(str);
    return "*******" + str.substr(str.length - 4);
  },
  /** 统一社会信用代码、税务登记编号、组织机构代码脱敏 */
  desensitizeLisenceNo(str: string) {
    str = String(str);
    if (str != null) {
      return str.substr(0, 6) + "******";
    }
  },
  /**
   * @method 检测用户登录状态 未登录/已过期 main.js中的全局守卫会用到，页面重定向到login登录页
   * @returns
   */
  getLoginStatus() {
    return new Promise((resolve, reject) => {
      request
        .rpc({ name: "protect.GetLoginStatus" })
        .then((result: any) => {
          utils.loginInfo(result.user);
          resolve(result);
        })
        .catch((error) => {
          utils.closeDialogGoToLogin();
          reject(error);
        });
    });
  },
  /** 处理登录信息 */
  loginInfo: (info: any) => {
    interface Privileges {
      [key: string]: any;
    }
    const user = info;
    const privileges: Privileges = {};
    roles = new Set();
    if (user && user.role) {
      roles.add(user.role.roleName);
      // 挂载登录用户权限,菜单,按钮显隐用
      user.privileges.forEach((item: any) => {
        if (item != null) {
          const index = item.lastIndexOf(".");
          const key = item.substring(index + 1, item.length);
          privileges[key] = item;
        }
      });
    }
    const userInfo = JSON.parse(JSON.stringify(user));
    delete userInfo.privileges;
    usePiniaStore().changeUserInfo(userInfo);
    usePiniaStore().changePrivileges(privileges);
  },
  /** 控制台打印信息  */
  consoleLog(data: { title: string; url: string; color: string; res: {} }) {
    const title = data.title || "打印信息";
    const url = data.url || "";
    const color = data.color || "#4c9cf0";
    const res = data.res || {};
    console.log(
      `%c ${title}: ${url} %c`,
      `color: ${color};font-size: 12px;`,
      `color: #${color}`,
      res
    );
  },
  /** 关闭所有dialog对话框并返回登录页面 */
  closeDialogGoToLogin() {
    // 选择所有具有 'el-overlay' 和 'custom-dialog-box' 类名的元素
    const overlayElements = document.querySelectorAll(
      ".el-overlay, .custom-dialog-box"
    );
    // 遍历选中的元素并移除它们
    overlayElements.forEach((element) => {
      element.remove();
    });
    window.localStorage.removeItem("User");
    window.localStorage.removeItem("scap_token");
    usePiniaStore().changeUserInfo({});
    usePiniaStore().changePrivileges([]);
    homeStore().changeHomeTabs([]);
    homeStore().changeCheckedTab({
      tabName: "首页&joint&Desktop",
      compontentName: pageFiles.Desktop,
      params: {},
    });
    router.push({ path: "/login" });
  },
  /** 全局字典处理 */
  initDicts() {
    return new Promise((resolve, reject) => {
      const action = {
        model: {
          itemName: "",
          itemValue: "",
        },
        offset: 0,
        limit: 10000,
      };
      request
        .rpc({ name: "protect.dict.PageDicts", action })
        .then((result: any) => {
          interface DictItem {
            dictName: string;
            itemValue: string;
          }
          homeStore().changeDicts({});
          interface DictParents {
            [key: string]: {
              list?: any[]; // list 属性可以是一个数组，数组中的元素类型为 any
              [key: string]: any; // 允许其他任意属性
            };
          }
          const parents: DictParents = {};
          result.list.data.forEach((item: DictItem) => {
            if (item.dictName == "DEPOSIT_TYPE") {
              parents[item.dictName] = {};
            } else {
              parents[item.itemValue] = {};
            }
          });
          utils.findChildren(parents, result.list.data);
          // 过滤不必要的字典值
          interface DataItem {
            list?: any; // list 属性可以是任意类型
            [key: string]: any; // 允许其他任意属性
          }
          const data: Record<string, DataItem> = parents;
          const filteredData: Record<string, DataItem> = Object.fromEntries(
            Object.entries(data).filter(([key, value]) => {
              // 过滤条件：值不为 {} 且存在 list 属性
              return (
                JSON.stringify(value) !== "{}" && value.hasOwnProperty("list")
              );
            })
          );
          homeStore().changeDicts(filteredData);
          resolve(result);
        })
        .catch((error) => {
          reject(error);
          homeStore().changeDicts({});
        });
    });
  },
  findChildren(parents: any, datas: any) {
    datas.forEach((data: any) => {
      if (
        parents[data.dictName] !== undefined &&
        parents[data.dictName] !== null &&
        parents[data.dictName] !== ""
      ) {
        try {
          parents[data.dictName].list.push(data);
        } catch (e) {
          parents[data.dictName].list = [];
          parents[data.dictName].list.push(data);
        }
        parents[data.dictName][data.itemValue] = data.itemName;
      }
    });
  },
  /**
	 * 上传临时目录的（文件/图片）到OSS
	 * @param {*} data (文件/图片)list 可以单个也可以多个
	 */
	uploadImageOss(data:any ,mchtNo: any) {
		let datas = [];
		Array.isArray(data) ? (datas = data) : (datas = [data]);
		const action = {
			filePaths: datas,
			bucketType: "PRIVATE", // 存储空间类型，默认为私有空间（PRIVATE/PUBLIC）
			mchtNo:mchtNo ? mchtNo:""
		};
    return new Promise((resolve, reject) => {
      request
			.rpc({name: "protect.common.UploadFile", action})
			.then((res:any) => {
				console.log("上传影像平台成功", res);
        resolve(res)
			})
			.catch((err:any) => {
        console.log("上传影像平台失败", err);
				reject(err);
			});
    })
	},
  /** 从临时目录拿上传文件 */
  downloadImageOss(data: any) {
    const action = {
      filePath: data.filePath,
      isTmp: '1',//1代表临时目录
      downloadType: "PREVIEW", // 文件下载类型（PREVIEW/DOWNLOAD）
      bucketType: "PRIVATE", // 存储空间类型 默认为私有空间（PRIVATE/PUBLIC）
    };
    return new Promise((resolve, reject) => {
      request
        .rpc({ name: "protect.common.DownloadFile", action, customErrFlag: true })
        .then((res: any) => {
          if (res.fileUrl) {
            // 在内网和外网要根据请求的url来展示图片
            if (window.location.origin.indexOf('localhost') != -1 || window.location.origin.indexOf('127.0.0.1') != -1) {
              // 本地启动
              resolve({
                fileUrl: `/oss-private${res.fileUrl}`,
              });
            } else {
              // 线上
              resolve({
                fileUrl: `${window.location.origin}/${common.reqUrl}/oss-private${res.fileUrl}`,
              });
            }
          } else {
            utils.downloadImageOss0(data).then((res: any) => {
              resolve(res);
            }).catch((err) => {
              reject(err);
            })
          }
        })
        .catch((err: any) => {
          utils.downloadImageOss0(data).then((res: any) => {
            resolve(res);
          }).catch((err) => {
            reject(err);
          })
        });
    });
  },
  /** 从OSS上拿上传文件 */
  downloadImageOss0(data: any) {
    const action = {
      filePath: data.filePath,
      isTmp: '0',//0代表OSS上
      downloadType: "PREVIEW", // 文件下载类型（PREVIEW/DOWNLOAD）
      bucketType: "PRIVATE", // 存储空间类型 默认为私有空间（PRIVATE/PUBLIC）
    };
    return new Promise((resolve, reject) => {
      request
        .rpc({ name: "protect.common.DownloadFile", action })
        .then((res: any) => {
          if (res.fileUrl) {
            // 在内网和外网要根据请求的url来展示图片
            if (window.location.origin.indexOf('localhost') != -1 || window.location.origin.indexOf('127.0.0.1') != -1) {
              // 本地启动
              resolve({
                fileUrl: `/oss-private${res.fileUrl}`,
              });
            } else {
              // 线上
              resolve({
                fileUrl: `${window.location.origin}/${common.reqUrl}/oss-private${res.fileUrl}`,
              });
            }
          } else {
            reject();
          }
        })
        .catch((err: any) => {
          reject(err);
        });
    });
  },
    /**
   * 根据生成的路径下载
   *val  传入的路径
   */
	downloadFile:(val:string, name:string)=> {
		if (val) {
			const url = val;
			const link = document.createElement("a");
			link.target = "_blank";
			link.href = url;
			link.download = name ? name : "";
			link.click();
			URL.revokeObjectURL(url);
		}
  },
  /** 获取字典列表 */
  getDicts: (val: string[]) => {
    const homePinia = homeStore();
    const dictsAll = homePinia.dicts;
    const dicts: Record<string, any> = {};
    val.forEach((item: string) => {
      dicts[item] = dictsAll[item] || { list: [] };
    });
    return dicts;
  },
  /** 字典翻译 */
  dictsFormatter: (val: any, dict: string) => {
    const homePinia = homeStore();
    const dictsAll = homePinia.dicts;
    if ((val != null && val != undefined && val != "") || val == 0) {
      if (dictsAll && dictsAll[dict]) {
        const dictObj = dictsAll[dict];
        return dictObj[val] ? dictObj[val] : val;
      } else {
        return val;
      }
    } else {
      return "-";
    }
  },
  /** 将时间戳改为固定格式（2020-20-20 10:09:09) */
  formatTimestamp: (timestamp: number, type: string, str: string) => {
    if (timestamp) {
      const date = new Date(timestamp);
      const year = date.getFullYear();
      const month = String(date.getMonth() + 1).padStart(2, "0");
      const day = String(date.getDate()).padStart(2, "0");
      const hours = String(date.getHours()).padStart(2, "0");
      const minutes = String(date.getMinutes()).padStart(2, "0");
      const seconds = String(date.getSeconds()).padStart(2, "0");
      if (type) {
        if (type == "date") {
          if (str) {
            return `${year}${month}${day}`;
          } else {
            return `${year}-${month}-${day}`;
          }
        } else if (type == "month") {
          if (str) {
            return `${year}${month}`;
          } else {
            return `${year}-${month}`;
          }
        } else if (type == "time") {
          if (str) {
            return `${hours}${minutes}${seconds}`;
          } else {
            return `${hours}:${minutes}:${seconds}`;
          }
        } else {
          return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
        }
      } else {
        return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
      }
    } else {
      return "";
    }
  },
  /**
	 * 查询是否有此权限（数组：因为可能一个按钮存在多个接口情况）
	 * @param {*} arr 数组，权限接口名称，是否有数组里这些权限，
	 * @returns 全都有则返回true，否则false
	 */
  ifThereIsPrivileges(arr: string[]): boolean {
    const privileges = usePiniaStore().privileges;
    return arr.every((item) => Object.values(privileges).includes(item));
  },
	/**
	 * 查询是否有此权限（数组）
	 * @param {*} arr 数组，权限接口名称，是否有数组里这些权限，
	 * @returns 只要有一个就是true
	 */
	ifThereIsPrivilegesOne(arr: string[]): boolean {
    const privileges = usePiniaStore().privileges;
    return arr.some((item) => Object.values(privileges).includes(item));
  },
};
export default utils;
